// EnumStringConverter.cs
//
// Copyright (c) 2007 Mike Strobel
//
// This source code is subject to the terms of the Microsoft Reciprocal License (Ms-RL).
// For details, see <http://www.opensource.org/licenses/ms-rl.html>.
//
// All other rights reserved.

using System;
using System.Globalization;
using System.IO;
using System.Windows.Data;

using Supremacy.Client.Data;
using Supremacy.Data;
using Supremacy.Game;
using Supremacy.Resources;

namespace Supremacy.Client
{
    [ValueConversion(typeof(String), typeof(String))]
    public class EnumStringConverter : ValueConverter<EnumStringConverter>
    {
        #region Fields
        private static readonly TableMap EnumTables;
        #endregion

        #region Properties
        public bool AccessText { get; set; }
        #endregion

        #region Constructors
        static EnumStringConverter()
        {
            EnumTables = TableMap.ReadFromFile(
                Path.Combine(
                    PathHelper.GetWorkingDirectory(),
                    @"Resources\Tables\EnumStrings.txt"));
        }
        #endregion

        #region IValueConverter Members
        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
                return null;

            var enumValue = value as Enum;
            string[] values = null;

            if (enumValue != null)
            {
                values = new[] { enumValue.GetType().Name, enumValue.ToString() };
            }

            object result = value;
            if (values == null)
            {
                try
                {
                    values = value.ToString().Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
                }
                catch {}
            }

            if ((values == null) || (values.Length != 2))
                return value;

            try
            {
                if (values.Length == 2)
                {
                    result = EnumTables[values[0]][values[1]][0];
                }
            }
            catch {}

            if ((result != null) && (parameter != null))
            {
                if (parameter.ToString() == "UpperCase")
                {
                    result = result.ToString().ToUpperInvariant();
                }
                else if ((result is Enum) && (parameter is string))
                {
                    try
                    {
                        result = EnumTables[parameter.ToString()][result.ToString()][0];
                    }
                    catch {}
                }
            }

            var resultText = result as string;
            if (resultText != null)
                result = resultText.Replace("&", this.AccessText ? "_" : "");

            return result;
        }

        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;
        }
        #endregion
    }

    [ValueConversion(typeof(String), typeof(Array))]
    public class EnumValueCollectionConverter : IValueConverter
    {
        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            object result = value;
            try
            {
                Type enumType = Type.GetType(value.ToString());
                if (enumType != null)
                {
                    return Enum.GetValues(enumType);
                }
            }
            catch {}
            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;
        }
        #endregion
    }

    [ValueConversion(typeof(String), typeof(String))]
    public class AltEnumStringConverter : IValueConverter
    {
        #region Fields
        private readonly TableMap _enumTables;
        #endregion

        #region Constructors
        public AltEnumStringConverter()
        {
            if (GameContext.Current != null)
            {
                _enumTables = GameContext.Current.Tables.EnumTables;
            }
            else if (Designer.IsInDesignMode)
            {
                _enumTables = TableMap.ReadFromFile(
                    Path.Combine(
                        PathHelper.GetWorkingDirectory(),
                        @"Resources\Tables\EnumStrings.txt"));
            }
            else
            {
                _enumTables = TableMap.ReadFromFile(
                    Path.Combine(
                        Environment.CurrentDirectory,
                        @"Resources\Tables\EnumStrings.txt"));
            }
        }
        #endregion

        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            object result = value;
            try
            {
                string memberName = value.ToString();
                string typeName = parameter.ToString();
                if ((memberName != null) && (typeName != null))
                {
                    result = _enumTables[typeName][memberName][0];
                }
            }
            catch {}
            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;
        }
        #endregion
    }

    [ValueConversion(typeof(object), typeof(String))]
    public sealed class FormatStringConverter : ValueConverter<FormatStringConverter>
    {
        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
                return null;
            if (parameter == null)
                return value.ToString();
            return String.Format("{0:" + parameter + "}", value);
        }

        public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;
        }

        public override object MultiConvert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var formatString = parameter as string;
            if (formatString == null)
                return null;

            return string.Format(
                formatString,
                values);
        }
    }

    [ValueConversion(typeof(object), typeof(string))]
    public sealed class StringFormatConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var formatString = parameter as string;
            if (formatString == null)
                return String.Empty;
            return String.Format(formatString, values);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            return new object[0];
        }
    }
}